package RockPaperScissors
{
    public class RepeatableProcessor implements IProcessable
    {
        protected var _onComplete:Function;
        protected var _onFail:Function;
        protected var _workflow = [];
        protected var _repeat_count:int = 0;
        protected var _workflow_archetype:Array;
        
        public function Processor(onComplete:Function = null, onFail:Function = null, steps:int=1)
        {
            this._onComplete = onComplete;
            this._onFail = onFail;
            this._repeat_count = steps;
        }
        
        protected function setupProcessor(onComplete:Function, onFail:Function, processSteps:Array, repeat=null)
        {
            this._onComplete = onComplete;
            this._onFail = onFail;
            
            this._workflow = processSteps;
            this._workflow_archetype = cloneArray(this._workflow);
            
            if(repeat != null) this._repeat_count = repeat;
        }
        
        private function cloneArray(from_array:Array):Array
        {
            var to_array:Array;
            to_array = new Array();
            for each(var item in from_array)
            {
                to_array.push(item);
            }
            
            return to_array;
        }

        public function Process(data)
        {
            var taskType:Class = this._workflow.pop() as Class;
            
            new taskType(this.ProcessingComplete, this._onFail).Process(data);
        }

        ///This will be invoked by one of the processors.
        ///If there are processors that haven't run yet then
        ///this function will process those instead of 
        ///running onComplete.
        private function ProcessingComplete(data)
        {
            if(this._workflow.length > 0)
            {
                this.Process(data);
            } 
            else 
            {
                _repeat_count = _repeat_count-1;
                
                if(_repeat_count == 0)
                {
                    this._onComplete(data);
                } 
                else 
                {
                    this._workflow = cloneArray(this._workflow_archetype);
                    this.Process(data);
                }
             }
        }
        
        
    }
}